#pragma once
#include "base/Task.h"
#include "base/RefCounted.h"
#include "base/Lock.h"
#include "MessageLoop.h"

namespace xBase
{
    class CxIOHandler;

    struct CxIOContext 
    {
        OVERLAPPED m_Overlapped;
        CxIOHandler* m_pHandler;
    };

    class CxIOHandler {
    public:
        virtual ~CxIOHandler() {}
        // This will be called once the pending IO operation associated with
        // |context| completes. |error| is the Win32 error code of the IO operation
        // (ERROR_SUCCESS if there was no error). |bytes_transfered| will be zero
        // on error.
        virtual VOID OnIOCompleted(CxIOContext * pContext, DWORD dwBytesTransfered,
            DWORD dwError) = 0;
    };

    class CxMessageLoopProxy : public CRefCountedThreadSafe<CxMessageLoopProxy>
    {
        friend class CxMessageLoop;

    public:
        ~CxMessageLoopProxy();

        VOID PostTask(CTask* pTask);
        VOID PostDelayedTask(CTask* pTask, INT64 nDelayMilliSecond);
        VOID PostDelayedTaskForMainProcess(CTask* pTask, INT64 nDelayMilliSecond);
        VOID PostNonNestableTask(CTask* pTask);
        VOID PostNonNestableDelayedTask(CTask* pTask, INT64 nDelayMilliSecond);
        VOID SetRunNestMessageLoopAllowed(BOOL bAllowed);

        BOOL IsRunNestMessageLoopAllowed();
        BOOL RunNestMessageLoop();

        INT  RunDepth();

        VOID Quit();
        VOID QuitNow();

    private:
        // Can only be created by CThreadMessageLoop.
        CxMessageLoopProxy(CxMessageLoop* pTargetMsgLoop);

        VOID PostTask_Helper(CTask* pTask, INT64 nDelayMilliSecond, BOOL bNestable);

        // Called directly by CThreadMessageLoop::~CThreadMessageLoop.
        VOID WillDestroyCurrentMessageLoop();

    private:
        CxLock          m_msgLoopLock;
        CxMessageLoop*  m_pTargetMsgLoop;

        DISALLOW_COPY_AND_ASSIGN(CxMessageLoopProxy);
    };
}